Skip to content

fix(agents): default-deny args keys in from_config() YAML loads#5533

Open
vexlorn wants to merge 2 commits intogoogle:mainfrom
vexlorn:fix/codeconfig-args-default-denylist
Open

fix(agents): default-deny args keys in from_config() YAML loads#5533
vexlorn wants to merge 2 commits intogoogle:mainfrom
vexlorn:fix/codeconfig-args-default-denylist

Conversation

@vexlorn
Copy link
Copy Markdown

@vexlorn vexlorn commented Apr 28, 2026

Summary

  • from_config(config_path, *, trusted=False) rejects YAML configs containing args keys by default
  • _load_config_from_path accepts a matching trusted parameter; gate logic is if not trusted or _ENFORCE_DENYLIST
  • External-facing call sites (cli_deploy.py Agent Engine deployment template, cli/utils/agent_loader.py) inherit the secure default with no caller-side change
  • Operator-controlled trusted loaders pass trusted=True explicitly
  • Legacy _set_enforce_denylist(True) preserved as a force-on override; _set_enforce_denylist(False) is a no-op since the default is now block

This is one of the three fixes proposed in #5532. The other two (default-on of the existing global flag, UntrustedCodeConfig type split) are larger or breaking; this one is the smallest non-breaking change that closes the sink at the boundary.

Threat model

config_agent_utils.from_config() and its private callee _load_config_from_path() reach resolve_code_reference(), which imports a Python callable named in YAML and invokes it with attacker-supplied positional and keyword arguments when the YAML contains an args key. v1.31.1 added _check_yaml_for_blocked_keys but gated it behind an opt-in flag that is not set by the call sites listed below.

Reachable from:

  • src/google/adk/cli/cli_deploy.py:113 — Agent Engine deployment template: root_agent = config_agent_utils.from_config(config_path)
  • src/google/adk/cli/utils/agent_loader.py:173_load_from_yaml_config() for adk run, adk web, adk deploy

After this PR, both call sites use the default trusted=False and the denylist runs.

Test plan

  • test_agent_config_litellm_model_with_custom_args — updated to pass trusted=True (operator-authored model_code with class-constructor args; legitimate)
  • test_agent_config_legacy_model_mapping_still_supported — updated to pass trusted=True (same legitimate pattern, legacy field mapping)
  • test_load_config_from_path_blocks_args_when_enforced — unchanged; legacy global flag still triggers block
  • test_from_config_blocks_args_by_default — new; default from_config() rejects args
  • test_from_config_allows_args_when_trusted — new; trusted=True accepts the same YAML
  • test_from_config_default_blocks_os_system_in_output_schema — new; concrete RCE PoC blocked, marker file not created

All 35 tests in tests/unittests/agents/test_agent_config.py pass locally (pytest -v).

Out of scope

  • resolve_agent_reference() (sub-agent loading) does not currently propagate trusted. If the parent is trusted=True, sub-agents loaded via config_path revert to default trusted=False. Maintainer to decide propagation policy.
  • UntrustedCodeConfig type split (issue option 3) — separate larger PR.
  • Removal of legacy _set_enforce_denylist API — separate cleanup.

Disclosure

Reported via g.co/vulnz on 2026-04-18 (Issue Tracker #503880658). Closed Won't Fix (Intended Behavior) on 2026-04-28. Filing per maintainer guidance to pursue fix via public channels.

Refs #5532.

`from_config()` now requires explicit `trusted=True` to allow `args` keys in
YAML agent configs. Default behavior rejects `args` before it reaches the
`resolve_code_reference` sink that calls the named callable.

External-facing call sites (`cli_deploy.py` Agent Engine deployment template,
`cli/utils/agent_loader.py` `adk run`/`adk web`/`adk deploy`) inherit the
secure default with no caller-side change. Operator-controlled trusted
loaders pass `trusted=True` explicitly.

Legacy `_set_enforce_denylist(True)` flag is preserved as a force-on
override for callers that already depend on it; `False` is now a no-op
since the denylist is default-on.

Refs google#5532
@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Apr 28, 2026
@rohityan rohityan self-assigned this Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants